package com.example.qihuibao.base

import android.app.Activity
import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.example.qihuibao.bean.DeviceBean
import com.example.qihuibao.constant.Config
import com.example.qihuibao.module.login.LoginActivity
import com.example.qihuibao.module.main.MainActivity
import com.example.qihuibao.module.service.ConnectService
import com.example.qihuibao.module.service.SerialPortService
import com.example.qihuibao.module.setting.SettingActivity
import com.example.qihuibao.utils.*
import com.example.qihuibao.utils.extension.toast
import com.example.qihuibao.widget.dialog.LoadingDialog
import com.example.qihuibao.widget.dialog.ProgressDialog
import com.example.qihuibao.widget.dialog.YesOrNoDialog
import com.google.gson.Gson
import com.gyf.immersionbar.ImmersionBar
import com.koushikdutta.async.http.WebSocket
import com.maning.updatelibrary.InstallUtils


/**
 *@author: cww
 *@desc: activity的基类 (尽量不要在基类添加一些额外的方法例如getLayoutId()，这样并不利于新手，也感觉奇怪)
 * 从整体来看，基类的设计必须是一个abstract class，并且提供必要的钩子函数给子类定制以及提供公共的常用的函数
 * 在基类的生命周期函数里面可以做一些统一的操作，一般来说是页面的打点
 * 对于Activity而言，有一些页面可能需要右滑返回功能，我们直接让BaseActivity继承SwipeBackActivity
 *@date: 4/17/23 10:05 PM
 */
abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInflater) -> T) : AppCompatActivity() {
    companion object {
        fun start(srcActivity: Activity, dstActivityCls:Class<out AppCompatActivity>) {
            val intent = Intent(srcActivity, dstActivityCls)
            srcActivity.startActivity(intent)
        }
        //串口二维码有关
        private var serialPortServiceConnection: ServiceConnection? = null
        private var connectServiceConnection: ServiceConnection? = null
        private var connectService: ConnectService? = null
        private var qrCodeBack:((code:String)->Unit)? = null
    }
    protected lateinit var viewBinding: T
    private var loadingDialog: LoadingDialog? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LOW_PROFILE
                or View.SYSTEM_UI_FLAG_FULLSCREEN
                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_IMMERSIVE)
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
        RxDevicesTool.navigation(this, false)
        viewBinding = inflater(layoutInflater)
        setContentView(viewBinding.root)

        if (enableImmersionBar()) {
            ImmersionBar.with(this)
                .statusBarColor(statusBarColor())//设置状态栏颜色，不设为透明
                .fitsSystemWindows(true)  //使得activity布局不要顶上状态栏
                .init();
        }

        if (this is MainActivity) {
            openSerialPort()
            startGroupListener()
        }else if (this is SettingActivity) {
            //
        }
    }

    override fun onStart() {
        super.onStart()
        //这里可以添加页面打点
    }

    override fun onPause() {
        super.onPause()
        qrCodeBack = null//保证当前activity才能获得串口二维码
    }

    override fun onStop() {
        super.onStop()
        //这里可以添加页面打点
    }

    /**
     * 开启沉浸状态栏
     */
    open fun enableImmersionBar() = false

    /**
     * 状态栏颜色
     */
    open fun statusBarColor() = android.R.color.transparent

    protected fun showLoading(show:Boolean, tag:String="正在加载") {
        if (show) {
            if (loadingDialog != null) {
                loadingDialog?.dismiss()
                loadingDialog = null
            }
            loadingDialog = LoadingDialog(tag)
            loadingDialog?.show(supportFragmentManager, "loading")
        }else {
            loadingDialog?.dismiss()
        }
    }

    private fun openSerialPort() {
        if (serialPortServiceConnection == null) {
            serialPortServiceConnection = object:ServiceConnection{
                override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                    val binder: SerialPortService.MyBinder = service as SerialPortService.MyBinder
                    binder.getService().setCallback(object:SerialPortService.CallBack{
                        override fun openBack(success: Boolean) {
                            if (!success) {
                                toast("串口打开失败，扫码不可用！")
                            }
                        }

                        override fun getCode(code: String) {
                            LogUtil.e("read qrcode=$code")
                            runOnUiThread {
                                qrCodeBack?.invoke(code)
                            }
                        }
                    })
                }

                override fun onServiceDisconnected(name: ComponentName?) {}
            }
            val intent = Intent(this, SerialPortService::class.java)
            bindService(intent, serialPortServiceConnection!!, BIND_AUTO_CREATE)
            startService(intent)
        }
    }

    //侦听组播
    private fun startGroupListener() {
        if (connectServiceConnection == null) {
            connectServiceConnection = object:ServiceConnection{
                override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                    connectService = (service as ConnectService.MyBinder).getService()
                    connectService?.setCallback(object:ConnectService.CallBack{
                        override fun getServerGroup(message: String) {
                            runOnUiThread {
                                toast("receive: $message")
                                val deviceBean = Gson().fromJson(message, DeviceBean::class.java)
                                if (deviceBean != null) {
                                    if (deviceBean.ip == IpUtil.getHostIP()) {
                                        toast("自身发送的，不处理")
                                    }else {
                                        if (deviceBean.isServer) {//from server
                                            if (deviceBean.targetIp.isEmpty() || deviceBean.targetIp == IpUtil.getHostIP()) {
                                                if (Config.isServerStation) {
                                                    //进入终端模式
                                                    connectService?.stopServer()
                                                    Config.isServerStation = false
                                                }
                                                if (Config.serverIp != deviceBean.ip) {
                                                    Config.serverIp = deviceBean.ip

                                                }
                                                connectService?.startConnect(
                                                    {success, errMsg ->
                                                        toast("startConnect: $success $errMsg")
                                                    },
                                                    {
                                                        //close
                                                    }
                                                )
                                            }else {
                                                //服务站发给其它终端的，不处理
                                            }
                                        }else {//from client
                                            if (Config.isServerStation) {
                                                Thread { ConnectUtil.groupSend(deviceBean.ip) }.start()//发送一次组播，目的是告诉client我的IP
                                            }else {
                                                //终端之间不处理组播
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    })
                    if (Config.isServerStation) {
                        //启动服务
                        connectService?.startServer()
                        toast("startServer")
                    }
                    Thread {
                        ConnectUtil.groupSend()//启动时无论服务站或终端都发送一次组播，目的是(终端)获得服务站的ip或(服务站)广播ip给所有的终端
                    }.start()
                }

                override fun onServiceDisconnected(name: ComponentName?) {}
            }
            val intent = Intent(this, ConnectService::class.java)
            bindService(intent, connectServiceConnection!!, BIND_AUTO_CREATE)
            startService(intent)
        }
    }

    //二维码回调
    fun getQRCode(back:(code:String)->Unit) {
        qrCodeBack = back
    }

    fun checkAppVersion() {
        UpgradeAppUtil.checkNewVersion {
            if (it.hasNewVersion == true) {
                YesOrNoDialog("发现新版本", "是否立即升级？") {ok->
                    if (ok) {
                        var pbDialog:ProgressDialog? = null
                        val apkPath = "${UpgradeAppUtil.apkDir}${it.version}.apk"
                        InstallUtils.with(this)
                            .setApkUrl("${it.apkUrl}")
                            .setApkPath(apkPath)
                            .setCallBack(object: InstallUtils.DownloadCallBack{
                                override fun onStart() {
                                }

                                override fun onComplete(path: String?) {
                                    LogUtil.e("install path=$path")
                                    pbDialog?.dismiss()
                                    InstallUtils.installAPK(this@BaseActivity, path, null)
                                }

                                override fun onLoading(total: Long, current: Long) {
                                    if (pbDialog == null) {
                                        pbDialog = ProgressDialog()
                                        pbDialog?.show(supportFragmentManager, "UpgradeApp")
                                        pbDialog?.setMax(total.toInt())
                                    }
                                    pbDialog?.setProgress(current.toInt())
                                    LogUtil.e("total=$total, current=$current")
                                }

                                override fun onFail(e: Exception?) {
                                    LogUtil.e("e=${e?.message}")
                                }

                                override fun cancle() {
                                    //
                                }
                            })
                            .startDownload()
                    }
                }.show(supportFragmentManager, "UpgradeApp")
            }
        }
    }

    fun configServerStation() {

    }

}